﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vds2465Telegrams
{
	public abstract class UserData_AsciiBytes : UserData
	{
		#region private member variables

		private byte[] _asciiBytes;

		#endregion private member variables

		#region constructor

		public UserData_AsciiBytes(byte dataType, int maxNrOfChars, string asciiString)
			: base(dataType)
		{
			if (String.IsNullOrEmpty(asciiString) == false)
			{
				if (asciiString.Length <= maxNrOfChars)
				{
					_asciiBytes = new byte[asciiString.Length];
					for (int index = 0; index < asciiString.Length; index++)
					{
						_asciiBytes[index] = (byte) asciiString[index];
					}
				}
				else
				{
					// TODO handle error - too many chars

					// we simply cut the string off
					_asciiBytes = new byte[maxNrOfChars];
					for (int index = 0; index < maxNrOfChars; index++)
					{
						_asciiBytes[index] = (byte)asciiString[index];
					}
				}
			}
			else
			{
				// TODO handle error or warning - empty asciiString
				_asciiBytes = new byte[0];
			}
		}

		public UserData_AsciiBytes(byte dataType, int maxNrOfChars, byte[] asciiBytes)
			: base(dataType)
		{
			if (asciiBytes != null)
			{
				if (asciiBytes.Length <= maxNrOfChars)
				{
					_asciiBytes = new byte[asciiBytes.Length];
					for (int index = 0; index < asciiBytes.Length; index++)
					{
						_asciiBytes[index] = asciiBytes[index];
					}
				}
				else
				{
					// TODO handle error - too many bytes

					// we simply cut the string off
					_asciiBytes = new byte[maxNrOfChars];
					for (int index = 0; index < maxNrOfChars; index++)
					{
						_asciiBytes[index] = asciiBytes[index];
					}
				}
			}
			else
			{
				// TODO handle error or warning - null asciiBytes
				_asciiBytes = new byte[0];
			}
		}

		public UserData_AsciiBytes(byte dataType)
			: base(dataType)
		{
			// the asciiBytes are set later via 'SetAsciiBytes'
		}

		#endregion constructor

		#region getters

		public byte[] GetCopyOfAsciiBytes()
		{
			if (_asciiBytes != null)
			{
				// we return a copy so that this object remains immutable
				byte[] retBytes = new byte[_asciiBytes.Length];
				for (int index = 0; index < _asciiBytes.Length; index++)
				{
					retBytes[index] = _asciiBytes[index];
				}
				return retBytes;
			}

			return new byte[0];
		}

		#endregion getters

		#region set AsciiBytes

		protected void SetAsciiBytes(byte[] asciiBytes)
		{
			if (asciiBytes != null)
			{
				_asciiBytes = new byte[asciiBytes.Length];
				for (int index = 0; index < _asciiBytes.Length; index++)
				{
					_asciiBytes[index] = asciiBytes[index];
				}
			}
			else
			{
				// TODO handle error
				_asciiBytes = new byte[0];
			}
		}

		#endregion set AsciiBytes

		#region ToString, Equals, GetHashCode

		public override int GetHashCode()
		{
			int hashCode = base.GetHashCode();
			hashCode ^= UserDataCommon.GetHashCode_ByteArray(_asciiBytes);			

			return hashCode;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("(");
			stringBuilder.Append(ToStringProperties());
			stringBuilder.Append(")");

			return stringBuilder.ToString();
		}

		internal override string ToStringProperties()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(base.ToStringProperties());

			stringBuilder.Append(", ");
			stringBuilder.Append(UserDataCommon.HexByteArrayToString("AsciiBytes", _asciiBytes));

			return stringBuilder.ToString();
		}

		public override bool Equals(object obj)
		{
			Type objType = obj.GetType();
			if (this.GetType() == objType)
			{
				UserData_AsciiBytes userData2Compare = obj as UserData_AsciiBytes;
				if (base.EqualsProperties(userData2Compare))
				{
					return EqualsProperties(userData2Compare);
				}
			}

			return false;
		}

		internal bool EqualsProperties(UserData_AsciiBytes userData2Compare)
		{
			if (base.EqualsProperties(userData2Compare))
			{
				return UserDataCommon.Equals2ByteArrays(_asciiBytes, userData2Compare.GetCopyOfAsciiBytes());
			}

			return false;
		}

		#endregion ToString, Equals, GetHashCode
	}
}
